<html>
  <h1>Woofs!</h1>

  <h2>Contents</h2>
  <h3><a href="readme.html#intro">1. Introduction </a></h3>
  <h3><a href="readme.html#installation">2. Installation </a></h3>
  <h3><a href="readme.html#usage">3. Usage        </a></h3>
  <h3><a href="readme.html#internals">4. Internals    </a></h3>
  <h4>&nbsp;&nbsp;&nbsp;&nbsp;<a href="readme.html#source_org">a. Source organization </a></h4>
  <h4>&nbsp;&nbsp;&nbsp;&nbsp;<a href="readme.html#plugins">b. Plugin system </a></h4>

  <br>

  <h2><a name="intro">Introduction</a></h2>
  <p>
  Woofs is a filesystem that transforms a source directory tree based on "tags"
  (key/value pairs gleaned in an arbitrary way from files) and "filters" 
  (possible keys).  Specifically, if F is a file in the source directory and
  L is a user-specified list of filters, the following occurs:
  <br>
  <pre>
  <code>
    Ftags = getTags(F);           // Ftags is a dictionary of F's tags.
    newpath = "";
    for each filter in L {
        val = Ftags.lookup(filter);
        newpath += "/" + val;
    }    
    newpath += "/" + F;
    // newpath now contains the path to F relative to the mount directory.
  </code>
  </pre>

  For example, suppose L is {"author", "subject", "blah"}, and F is a file
  named "tacosort.txt", with tags 
    {"author" => "Michael", "subject" => "algorithms", "blah" => 42}.
  Then F's relative path in the mounted directory would be "Michael/algorithms/42/tacosort.txt".
  Once mounted, the directory can be accessed like any other.
  </p>

  <h2><a name="installation">Installation</a></h2>
  <p>
  NOTE: This stuff is subject to change, as I'm not quite done with packaging and build pretties.
  <br>
  To install, you'll first need to set up FUSE (link somewhere below) and insert the kernel module
  ("modprobe fuse" as root on Linux).  Following this, do the following in the main directory of
  the woofs source:

  <pre><code>
    make
  </code></pre>
  The plugins are built similarly.  They result in shared libraries, which can be copied to whatever
  plugin directory you choose.
  </p>

  <h2><a name="usage">Usage</a></h2>
  <p>
  To mount:
  <br>
  woofs &lt;source directory&gt; &lt;mount directory&gt; &lt;plugin directory&gt; &lt;filter 1&gt; ...
  <br><br>
  source directory - A directory of tagged files.  Must exist.
  <br>
  mount directory - The directory into which the constructed directory tree should go.  Must exist.
  <br>
  plugin directory - A directory with woofs plugins (shared libraries).  Must exist.
  <br>
  filters - Arbitrary strings used for directory tree construction as described above.
  <br><br>
  Example: woofs ./sourcedir ./mountdir ./plugins author subject blah
  </p>

  <h2><a name="internals">Internals</a></h2>
  <p>
  Woofs is implemented using the FUSE (Filesystem in USErspace) API
  (<a href="http://fuse.sourceforge.net/">http://fuse.sourceforge.net/</a>).  
  Initially, it loads format plugins and creates a directory tree model of the mounted system, which it
  queries in filesystem interface functions.  These interface functions, including
  read(), write(), readdir(), open(), etc., are called by FUSE when a program (such
  as a text editor or audio file player) calls their standard library counterparts.
  </p>

  <h3><a name="source_org">Source Organization</a></h3>
  <p>
  woofs.c - Implements filesystem interface functions, builds the mount directory
  tree, and contains main().
  <br><br>
  tags.c - Routines for harvesting tags from files and placing them into abstract
  "tag sets" that can be queried by key.
  <br><br>
  dirtree.c - Routines for constructing, maintaining, and querying the mount directory
  tree.
  <br><br>
  plugin.c - Routines for registering, loading, and accessing file tag harvesting plugins.
  <br><br>
  woofs_plugin.h - Included by all plugins.
  <br><br>
  path.c - Routines for path string manipulation.
  <br><br>
  strfuncs.c - Routines for string concatenation and whatnot.
  <br><br>
  list.c - A linked list.
  </p>

  <h3><a name="plugins">The Plugin System</a></h3>
  <p>
  Plugins do the tag harvesting.  Since there are many different types of tags (and 
  multiple definitions of "tag"), there is a plugin for each supported tag/file format (Multiple formats
  can share a plugin, though.).  Each plugin must implement the following functions:

  <pre>
  <code>
  void init (void) - Do any initialization stuff for the plugin.  Called when it's loaded.

  void fini (void) - Do any cleanup stuff for the plugin.  Called when it's unloaded.

  int claim_file (int fd, char *filepath) - Return 0 if the plugin can handle the given file, nonzero otherwise.

  void get_tags (int fd, char *filepath, void *tag_set, tag_set_filler filler_function) - Harvest all tags from the
  given file using the given tag_set_filler function.  Called if and only if claim_file() returned nonzero.
  </code>
  </pre>

  Note that these can have other names, but pointers to them must be stored in a struct of type woofs_format_plugin
  (whose definition is in woofs_plugin.h) named woofs_struct.  In addition to the function pointers, 
  woofs_struct.magic must be set to WOOFS_PLUGIN_MAGIC (0xb00bcafe).  See the provided plugins for examples.
  </p>

</html>
